package fem3d;

import java.util.ArrayList;

import fem2.AbstractStructuralStaticDemo;
import fem2.Constraint;
import fem2.Element;
import fem2.GravityLoad;
import fem2.Load;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshGenerator;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Node;
import fem2.element.BBarStructuralElement;
import fem2.element.StructuralElement;
import fem2.enu.State;
import fem2.material.StVenantKirchhoffMM;
import fem2.pre_and_post.GidMeshGenerator;

/**
 * Cube model to test various method to cue with incompresibility
 * 
 * @author hbui
 * 
 */
public class Cube extends AbstractStructuralStaticDemo {

	public Cube() {
		projectDir = "/home/hbui/kratos_janosch";
		projectName = "cube.gid";
		meshFileName = "mesh3.msh";
	}

	@Override
	public Mesh createMesh() {
		String fn = projectDir + '/' + projectName + '/' + meshFileName;
		MeshGenerator mg = new GidMeshGenerator(fn);
		Mesh mesh = mg.getMesh(3);
		return mesh;
	}

	@Override
	public Model createConditions(Model m) {
		Mesh mesh = m.getMesh();

		Constraint cx = new Constraint(false, true, true);
		Constraint cy = new Constraint(true, false, true);
		Constraint cz = new Constraint(true, true, false);

		ArrayList<Node> bottom = MeshUtilities.seekNodesOnSurface(mesh, 0.0, 0.0, 1.0, 0.0);
		ArrayList<Node> sidex1 = MeshUtilities.seekNodesOnSurface(mesh, 1.0, 0.0, 0.0, 0.0);
		ArrayList<Node> sidex2 = MeshUtilities.seekNodesOnSurface(mesh, 1.0, 0.0, 0.0, -1.0);
		ArrayList<Node> sidey1 = MeshUtilities.seekNodesOnSurface(mesh, 0.0, 1.0, 0.0, 0.0);
		ArrayList<Node> sidey2 = MeshUtilities.seekNodesOnSurface(mesh, 0.0, 1.0, 0.0, -1.0);

		mesh.addConstraint(cz, bottom);
		mesh.addConstraint(cx, sidex1);
		mesh.addConstraint(cx, sidex2);
		mesh.addConstraint(cy, sidey1);
		mesh.addConstraint(cy, sidey2);

		double density = 2e3;
		for (int i = 0; i < mesh.countBlocks(); i++) {
			Load l = new GravityLoad(mesh.getBlock(i), density);
			m.addLoad(l);
		}

		return m;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 20e6;
		double nu = 0.49;
		double thickness = 1.0;
		double rho = 0.0;
		State ss = State.THREE_DIMENSIONAL;
		return new StVenantKirchhoffMM(E, nu, thickness, rho, ss);
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		// StructuralElement e = new StructuralElement(mp, mm);

		StructuralElement e = new BBarStructuralElement(mp, mm);

		return e;
	}

	public static void main(String[] args) {
		AbstractStructuralStaticDemo demo = new Cube();

		demo.run();
	}
}
